using System;
using System.ComponentModel;
using System.IO;
using System.Management;
using System.Threading;
using RollManager.Library.Utils;

namespace RollManager.Library.ActionSteps
{
    [Serializable]
    public class StartServiceStep : ActionStep
    {
        public string m_serviceName = StepConstants.NAME;
        private bool m_waitForService = false;

        [DisplayName("Service Name")]
        [Description("The name of the service to be started.")]
        public string ServiceName
        {
            get
            {
                return m_serviceName;
            }
            set
            {
                if( string.IsNullOrEmpty( value ) )
                {
                    throw new ArgumentException( "Service Name cannot be empty." );
                }
                else
                {
                    m_serviceName = value.Trim();
                }
            }
        }

        [DisplayName("Wait For Service")]
        [Description("Indicates whether the step should wait until the service has started.")]
        public bool WaitForService
        {
            get
            {
                return m_waitForService;
            }
            set
            {
                m_waitForService = value;
            }
        }

        public override string Name
        {
            get { return "Start Service"; }
        }

        protected override void Run()
        {
            string command = Path.Combine( Common.PsToolsDir, "psservice.exe" );
            string args = string.Format( @"\\{0} start {1}", CurrentServer, m_serviceName );

            MethodRepeater.RepeatMethod( delegate
            {
                Common.RunCommand( command, args, Progress );
            }, Progress, 5 );

            if( !m_waitForService )
            {
                return;
            }

            // query service until started.
            while( true )
            {
                Thread.Sleep( 500 );

                ManagementObject obj = Common.GetService( CurrentServer, m_serviceName );
                string state = obj.Properties[ "State" ].Value.ToString();
                switch( state )
                {
                    case "Running":
                        return;

                    case "Stopped":
                        throw new Exception( "Service status was stopped." );
                }
            }
        }

        protected override void Simulate()
        {
            ManagementObject obj = Common.GetService( CurrentServer, m_serviceName );

            if( obj == null )
            {
                throw new Exception(
                    string.Format( "Could not find windows service {0} on {1}.", m_serviceName, CurrentServer ) );
            }

            Progress.AddFormat( "Simulated starting of {0} on {1}.", m_serviceName, CurrentServer );
        }
    }
}
